#ifndef UNIFIED_H
#define UNIFIED_H

#include "unicode/uchar.h"
#include "unicode/ustring.h"
#include "unicode/ustdio.h"
#include "types.h"

typedef struct {
  int saved_line;
  int line;
  int saved_column;
  int column;
  // Can we factor these out?
  int token_line;
  int token_column;
  int multiplier;
  UChar *filename;
  generic_list_t *spill;
  UFILE *in;
} tokenizer_t;

tokenizer_t *init_tokenizer(UFILE *filehandle, UChar *filename);
function_t *parse(UFILE *filehandle, UChar *filename, handler_t *handler);
void parse_exception(handler_t *handler, tokenizer_t *tokenizer, char *message);

int get_position(tokenizer_t *tokenizer);
void set_position(tokenizer_t *tokenizer, int line_number, call_t *call);

void push_position(tokenizer_t *tokenizer, int *line);
void pop_position(tokenizer_t *tokenizer, value_t *value, int line);
generic_list_t *value_position(value_t *value);

void ignore(tokenizer_t *tokenizer);
void consume_comment(tokenizer_t *tokenizer);
void consume_whitespace(tokenizer_t *tokenizer);

name_t *get_name(tokenizer_t *tokenizer, handler_t *handler);
UChar *get_identifier(tokenizer_t *tokenizer, handler_t *handler);

int starts_identifier(UChar character);
int in_identifier(UChar character);

/*Primitive Types */
number_t *get_number(tokenizer_t *tokenizer, handler_t *handler);
tag_t *get_tag(tokenizer_t *tokenizer, handler_t *handler);
string_types_t *get_string(tokenizer_t *tokenizer, handler_t *handler);
character_t *get_character(tokenizer_t *tokenizer, handler_t *handler);

/*Compound Types */
function_t *get_function(tokenizer_t *tokenizer, handler_t *handler);
generic_list_t *get_parameters(tokenizer_t *tokenizer, handler_t *handler, name_t **var_args, int *spill);
generic_list_t *get_function_body(tokenizer_t *tokenizer, handler_t *handler, call_t *spill);
list_types_t *get_list(tokenizer_t *tokenizer, handler_t *handler);
call_t *get_call(tokenizer_t *tokenizer, handler_t *handler);
call_t *get_nested_call(tokenizer_t *tokenizer, handler_t *handler);
UChar fget_character(tokenizer_t *tokenizer);
void freplace_character(tokenizer_t *tokenizer, UChar replace);


#endif // UNIFIED_H
